package indi.zhifa.study2025.oa.admin.facade.role.impl;

import indi.zhifa.engine.core.common.utils.DtoEntityUtil;
import indi.zhifa.engine.mpenhance.utils.DbDtoEntityUtil;
import indi.zhifa.study2025.oa.admin.facade.role.IRoleFacade;
import indi.zhifa.study2025.oa.dao.po.GenRoleEntity;
import indi.zhifa.study2025.oa.dao.po.GenRoleGroupEntity;
import indi.zhifa.study2025.oa.model.expose.role.dto.RoleCreateDto;
import indi.zhifa.study2025.oa.model.expose.role.dto.RoleEditDto;
import indi.zhifa.study2025.oa.model.expose.role.dto.RoleGroupCreateDto;
import indi.zhifa.study2025.oa.model.expose.role.dto.RoleGroupEditDto;
import indi.zhifa.study2025.oa.model.expose.role.vo.RoleAllVo;
import indi.zhifa.study2025.oa.model.expose.role.vo.RoleGroupAllVo;
import indi.zhifa.study2025.oa.model.expose.role.vo.RoleGroupVo;
import indi.zhifa.study2025.oa.model.expose.role.vo.RoleVo;
import indi.zhifa.study2025.oa.service.role.IRoleGroupService;
import indi.zhifa.study2025.oa.service.role.IRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Component
public class RoleFacadeImpl implements IRoleFacade {

    final IRoleService mRoleService;
    final IRoleGroupService mRoleGroupService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RoleGroupVo createRoleGroup(RoleGroupCreateDto pRoleGroupCreateDto) {
        GenRoleGroupEntity roleGroupEntity = DbDtoEntityUtil.createFromDto(pRoleGroupCreateDto, GenRoleGroupEntity.class);
        roleGroupEntity = mRoleGroupService.create(roleGroupEntity);
        RoleGroupVo rtn = DbDtoEntityUtil.createFromDto(roleGroupEntity, RoleGroupVo.class);
        return rtn;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RoleVo createRole(Long pGroupId, RoleCreateDto pRoleCreateDto) {
        GenRoleGroupEntity roleGroupEntity = mRoleGroupService.checkById(pGroupId);
        GenRoleEntity roleEntity = DbDtoEntityUtil.createFromDto(pRoleCreateDto, GenRoleEntity.class);
        roleEntity.setGroupId(roleGroupEntity.getId());
        roleEntity.setGroupCode(roleGroupEntity.getCode());
        roleEntity = mRoleService.create(roleEntity);
        RoleVo rtn = DbDtoEntityUtil.createFromDto(roleEntity, RoleVo.class);
        return rtn;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RoleGroupVo editRoleGroup(Long pId, RoleGroupEditDto pRoleGroupEditDto) {

        GenRoleGroupEntity roleGroupEntity = mRoleGroupService.edit(pId,pRoleGroupEditDto);
        RoleGroupVo rtn = DbDtoEntityUtil.createFromDto(roleGroupEntity, RoleGroupVo.class);
        return rtn;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RoleVo editRole(Long pId, RoleEditDto pRoleEditDto) {
        GenRoleEntity roleEntity = mRoleService.edit(pId,pRoleEditDto);
        RoleVo rtn = DbDtoEntityUtil.createFromDto(roleEntity, RoleVo.class);
        return rtn;
    }

    @Override
    public List<RoleGroupAllVo> list() {
        List<GenRoleGroupEntity> roleGroupEntities = mRoleGroupService.findAll();
        List<RoleGroupAllVo> rtn = DtoEntityUtil.trans(roleGroupEntities, RoleGroupAllVo.class);
        List<GenRoleEntity> roleEntityList = mRoleService.findAll();
        Map<Long,List<GenRoleEntity>> roleGroupList = roleEntityList.stream().collect(Collectors.groupingBy(GenRoleEntity::getGroupId));
        Map<Long,List<String>> roleMenuCodeList = mRoleService.getRelDepCodeList(null);
        Map<Long,List<String>> dataAuthCodeList = mRoleService.getRelAuthDataCodeList(null);

        for(RoleGroupAllVo roleGroupAllVo : rtn) {
            List<GenRoleEntity> roleEntities = roleGroupList.get(roleGroupAllVo.getId());
            List<RoleAllVo> roleVosList = DtoEntityUtil.trans(roleEntities, RoleAllVo.class);
            for(RoleAllVo roleVo : roleVosList) {
                List<String> depCodeList = roleMenuCodeList.get(roleVo.getId());
                if(null!= depCodeList){
                    roleVo.setMenuCodes(depCodeList);
                }
                List<String> authCodeList = dataAuthCodeList.get(roleVo.getId());
                if(null!= authCodeList){
                    roleVo.setDataAuthCodes(authCodeList);
                }
            }
            roleGroupAllVo.setRolls(roleVosList);
        }
        return rtn;
    }

    @Override
    public void assignMenu(Long pId, List<Long> pMenuIds) {
        mRoleService.setMenus(pId,pMenuIds);
    }
}
